/*
 * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package jdk.io;

/**
 * {@code DataInput} 接口提供了从二进制流中读取字节，
 * 并从中重构任意 Java 原始类型数据的功能。还提供了一种机制，
 * 可以从<a href="#modified-utf-8">修改版 UTF-8</a>格式的数据中重构 {@code String}。
 * <p>
 * 本接口中所有读取例程的一个共同点是：如果在读取所需字节数之前到达文件末尾，
 * 将抛出 {@code EOFException}（属于 {@code IOException} 的一种）。
 * 如果因文件结束以外的任何原因无法读取任何字节，将抛出除 {@code EOFException} 之外的 {@code IOException}。
 * 特别是，如果输入流已关闭，可能会抛出 {@code IOException}。
 *
 * <h3><a name="modified-utf-8">修改版 UTF-8</a></h3>
 * <p>
 * DataInput 和 DataOutput 接口的实现以稍微修改过的 UTF-8 格式表示 Unicode 字符串。
 *（关于标准 UTF-8 格式的信息，参见《Unicode 标准，版本 4.0》第 3.9 节“Unicode 编码形式”）。
 * 请注意，在下表中，最高有效位出现在最左侧的列中。
 *
 * <blockquote>
 *   <table border="1" cellspacing="0" cellpadding="8"
 *          summary="位值和字节">
 *     <tr>
 *       <th colspan="9"><span style="font-weight:normal">
 *         范围在 {@code '\u005Cu0001'} 到 {@code '\u005Cu007F'} 的所有字符用单个字节表示：</span></th>
 *     </tr>
 *     <tr>
 *       <td></td>
 *       <th colspan="8" id="bit_a">位值</th>
 *     </tr>
 *     <tr>
 *       <th id="byte1_a">字节 1</th>
 *       <td><center>0</center>
 *       <td colspan="7"><center>位 6-0</center>
 *     </tr>
 *     <tr>
 *       <th colspan="9"><span style="font-weight:normal">
 *         空字符 {@code '\u005Cu0000'} 和范围在 {@code '\u005Cu0080'} 到 {@code '\u005Cu07FF'} 的字符
 *         用一对字节表示：</span></th>
 *     </tr>
 *     <tr>
 *       <td></td>
 *       <th colspan="8" id="bit_b">位值</th>
 *     </tr>
 *     <tr>
 *       <th id="byte1_b">字节 1</th>
 *       <td><center>1</center>
 *       <td><center>1</center>
 *       <td><center>0</center>
 *       <td colspan="5"><center>位 10-6</center>
 *     </tr>
 *     <tr>
 *       <th id="byte2_a">字节 2</th>
 *       <td><center>1</center>
 *       <td><center>0</center>
 *       <td colspan="6"><center>位 5-0</center>
 *     </tr>
 *     <tr>
 *       <th colspan="9"><span style="font-weight:normal">
 *         范围在 {@code '\u005Cu0800'} 到 {@code '\u005CuFFFF'} 的 {@code char} 值
 *         用三个字节表示：</span></th>
 *     </tr>
 *     <tr>
 *       <td></td>
 *       <th colspan="8"id="bit_c">位值</th>
 *     </tr>
 *     <tr>
 *       <th id="byte1_c">字节 1</th>
 *       <td><center>1</center>
 *       <td><center>1</center>
 *       <td><center>1</center>
 *       <td><center>0</center>
 *       <td colspan="4"><center>位 15-12</center>
 *     </tr>
 *     <tr>
 *       <th id="byte2_b">字节 2</th>
 *       <td><center>1</center>
 *       <td><center>0</center>
 *       <td colspan="6"><center>位 11-6</center>
 *     </tr>
 *     <tr>
 *       <th id="byte3">字节 3</th>
 *       <td><center>1</center>
 *       <td><center>0</center>
 *       <td colspan="6"><center>位 5-0</center>
 *     </tr>
 *   </table>
 * </blockquote>
 * <p>
 * 此格式与标准 UTF-8 格式的区别如下：
 * <ul>
 * <li>空字节 {@code '\u005Cu0000'} 用 2 字节格式而不是 1 字节格式编码，
 *     以便编码后的字符串中永远不会嵌入空值。
 * <li>仅使用 1 字节、2 字节和 3 字节格式。
 * <li><a href="../lang/Character.html#unicode">补充字符</a>
 *     以代理对的形式表示。
 * </ul>
 * @author  Frank Yellin
 * @see     java.io.DataInputStream
 * @see     java.io.DataOutput
 * @since   JDK1.0
 */
public
interface DataInput {
    /**
     * 从输入流中读取一些字节并存储到缓冲区数组 {@code b} 中。
     * 读取的字节数等于 {@code b} 的长度。
     * <p>
     * 此方法将阻塞，直到以下任一条件发生：
     * <ul>
     * <li>{@code b.length} 字节的输入数据可用，此时正常返回。
     *
     * <li>检测到文件结束，此时抛出 {@code EOFException}。
     *
     * <li>发生 I/O 错误，此时抛出除 {@code EOFException} 之外的
     * {@code IOException}。
     * </ul>
     * <p>
     * 如果 {@code b} 为 {@code null}，则抛出 {@code NullPointerException}。
     * 如果 {@code b.length} 为零，则不读取任何字节。否则，
     * 读取的第一个字节存储到元素 {@code b[0]} 中，
     * 下一个字节存储到 {@code b[1]} 中，依此类推。
     * 如果从此方法抛出异常，则可能 {@code b} 的部分字节已用输入流中的数据更新，
     * 但并非全部字节。
     *
     * @param     b   读取数据的缓冲区。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    void readFully(byte b[]) throws IOException;

    /**
     * 从输入流中读取 {@code len} 字节。
     * <p>
     * 此方法将阻塞，直到以下任一条件发生：
     * <ul>
     * <li>{@code len} 字节的输入数据可用，此时正常返回。
     *
     * <li>检测到文件结束，此时抛出 {@code EOFException}。
     *
     * <li>发生 I/O 错误，此时抛出除 {@code EOFException} 之外的
     * {@code IOException}。
     * </ul>
     * <p>
     * 如果 {@code b} 为 {@code null}，则抛出 {@code NullPointerException}。
     * 如果 {@code off} 为负，或 {@code len} 为负，或 {@code off+len}
     * 大于数组 {@code b} 的长度，则抛出 {@code IndexOutOfBoundsException}。
     * 如果 {@code len} 为零，则不读取任何字节。否则，
     * 读取的第一个字节存储到元素 {@code b[off]} 中，
     * 下一个字节存储到 {@code b[off+1]} 中，依此类推。
     * 读取的字节数最多等于 {@code len}。
     *
     * @param     b   读取数据的缓冲区。
     * @param off  指定数据偏移量的整数。
     * @param len  指定要读取字节数的整数。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    void readFully(byte b[], int off, int len) throws IOException;

    /**
     * 尝试跳过输入流中的 {@code n} 字节数据，丢弃跳过的字节。
     * 但是，它可能会跳过较少数量的字节，甚至可能为零。
     * 这可能是由于多种条件导致的；在跳过 {@code n} 字节之前到达文件末尾只是其中一种可能性。
     * 此方法从不抛出 {@code EOFException}。
     * 返回实际跳过的字节数。
     *
     * @param      n   要跳过的字节数。
     * @return     实际跳过的字节数。
     * @exception  IOException   如果发生 I/O 错误。
     */
    int skipBytes(int n) throws IOException;

    /**
     * 读取一个输入字节，如果该字节非零则返回 {@code true}，如果该字节为零则返回 {@code false}。
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeBoolean} 方法写入的字节。
     *
     * @return     读取的 {@code boolean} 值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    boolean readBoolean() throws IOException;

    /**
     * 读取并返回一个输入字节。
     * 该字节被视为有符号值，范围在 {@code -128} 到 {@code 127}（含）之间。
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeByte} 方法写入的字节。
     *
     * @return     读取的 8 位值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    byte readByte() throws IOException;

    /**
     * 读取一个输入字节，将其零扩展为 {@code int} 类型，并返回结果，因此结果范围在 {@code 0} 到 {@code 255} 之间。
     * 如果 {@code writeByte} 的参数意图是 {@code 0} 到 {@code 255} 范围内的值，
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeByte} 方法写入的字节。
     *
     * @return     读取的无符号 8 位值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    int readUnsignedByte() throws IOException;

    /**
     * 读取两个输入字节并返回一个 {@code short} 值。
     * 设 {@code a} 为读取的第一个字节，{@code b} 为第二个字节。
     * 返回的值为：
     * <pre>{@code (short)((a << 8) | (b & 0xff))
     * }</pre>
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeShort} 方法写入的字节。
     *
     * @return     读取的 16 位值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    short readShort() throws IOException;

    /**
     * 读取两个输入字节并返回一个范围在 {@code 0} 到 {@code 65535} 之间的 {@code int} 值。
     * 设 {@code a} 为读取的第一个字节，{@code b} 为第二个字节。
     * 返回的值为：
     * <pre>{@code (((a & 0xff) << 8) | (b & 0xff))
     * }</pre>
     * 如果 {@code writeShort} 的参数意图是 {@code 0} 到 {@code 65535} 范围内的值，
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeShort} 方法写入的字节。
     *
     * @return     读取的无符号 16 位值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    int readUnsignedShort() throws IOException;

    /**
     * 读取两个输入字节并返回一个 {@code char} 值。
     * 设 {@code a} 为读取的第一个字节，{@code b} 为第二个字节。
     * 返回的值为：
     * <pre>{@code (char)((a << 8) | (b & 0xff))
     * }</pre>
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeChar} 方法写入的字节。
     *
     * @return     读取的 {@code char} 值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    char readChar() throws IOException;

    /**
     * 读取四个输入字节并返回一个 {@code int} 值。
     * 设 {@code a-d} 为读取的第一到第四个字节。返回的值为：
     * <pre>{@code
     * (((a & 0xff) << 24) | ((b & 0xff) << 16) |
     *  ((c & 0xff) <<  8) | (d & 0xff))
     * }</pre>
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeInt} 方法写入的字节。
     *
     * @return     读取的 {@code int} 值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    int readInt() throws IOException;

    /**
     * 读取八个输入字节并返回一个 {@code long} 值。
     * 设 {@code a-h} 为读取的第一到第八个字节。
     * 返回的值为：
     * <pre>{@code
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16) |
     *  ((long)(g & 0xff) <<  8) |
     *  ((long)(h & 0xff)))
     * }</pre>
     * <p>
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeLong} 方法写入的字节。
     *
     * @return     读取的 {@code long} 值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    long readLong() throws IOException;

    /**
     * 读取四个输入字节并返回一个 {@code float} 值。
     * 它首先以与 {@code readInt} 方法完全相同的方式构造一个 {@code int} 值，
     * 然后以与 {@code Float.intBitsToFloat} 方法完全相同的方式将此 {@code int} 值转换为 {@code float}。
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeFloat} 方法写入的字节。
     *
     * @return     读取的 {@code float} 值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    float readFloat() throws IOException;

    /**
     * 读取八个输入字节并返回一个 {@code double} 值。
     * 它首先以与 {@code readLong} 方法完全相同的方式构造一个 {@code long} 值，
     * 然后以与 {@code Double.longBitsToDouble} 方法完全相同的方式将此 {@code long} 值转换为 {@code double}。
     * 此方法适用于读取接口 {@code DataOutput} 的 {@code writeDouble} 方法写入的字节。
     *
     * @return     读取的 {@code double} 值。
     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。
     * @exception  IOException   如果发生 I/O 错误。
     */
    double readDouble() throws IOException;

    /**
     * 从输入流中读取下一行文本。
     * 它连续读取字节，将每个字节分别转换为字符，
     * 直到遇到行终止符或文件结束；然后将读取的字符作为 {@code String} 返回。
     * 请注意，由于此方法处理字节，因此不支持完整 Unicode 字符集的输入。
     * <p>
     * 如果在读取任何字节之前遇到文件结束，则返回 {@code null}。
     * 否则，读取的每个字节通过零扩展转换为 {@code char} 类型。
     * 如果遇到字符 {@code '\n'}，则将其丢弃并停止读取。
     * 如果遇到字符 {@code '\r'}，则将其丢弃，如果后续字节转换为字符 {@code '\n'}，
     * 则也将其丢弃；然后停止读取。
     * 如果在遇到字符 {@code '\n'} 和 {@code '\r'} 之前遇到文件结束，则停止读取。
     * 一旦停止读取，将返回一个 {@code String}，其中包含按顺序读取且未丢弃的所有字符。
     * 请注意，此字符串中的每个字符的值都将小于 {@code \u005Cu0100}，即 {@code (char)256}。
     *
     * @return 输入流中的下一行文本，如果在读取任何字节之前遇到文件结束则为 {@code null}。
     * @exception  IOException  如果发生 I/O 错误。
     */
    String readLine() throws IOException;

    /**
     * 读取使用<a href="#modified-utf-8">修改版 UTF-8</a>格式编码的字符串。
     * {@code readUTF} 的通用约定是它读取以修改版 UTF-8 格式编码的 Unicode 字符字符串的表示；
     * 然后将此字符字符串作为 {@code String} 返回。
     * <p>
     * 首先，读取两个字节并用于以与 {@code readUnsignedShort} 方法完全相同的方式构造一个无符号 16 位整数。
     * 此整数值称为<i>UTF 长度</i>，并指定要读取的额外字节数。
     * 然后，通过将这些字节分组考虑，将它们转换为字符。每个组的长度由组中第一个字节的值计算得出。
     * 组后的字节（如果有）是下一组的第一个字节。
     * <p>
     * 如果组的第一个字节匹配位模式 {@code 0xxxxxxx}（其中 {@code x} 表示“可以是 {@code 0} 或 {@code 1}"），
     * 则该组仅由该字节组成。该字节通过零扩展形成一个字符。
     * <p>
     * 如果组的第一个字节匹配位模式 {@code 110xxxxx}，则该组由字节 {@code a} 和第二个字节 {@code b} 组成。
     * 如果没有字节 {@code b}（因为字节 {@code a} 是要读取的最后一个字节），或者字节 {@code b} 不匹配位模式 {@code 10xxxxxx}，
     * 则抛出 {@code UTFDataFormatException}。否则，该组转换为字符：
     * <pre>{@code (char)(((a & 0x1F) << 6) | (b & 0x3F))
     * }</pre>
     * 如果组的第一个字节匹配位模式 {@code 1110xxxx}，则该组由字节 {@code a} 和另外两个字节 {@code b} 和 {@code c} 组成。
     * 如果没有字节 {@code c}（因为字节 {@code a} 是要读取的最后两个字节之一），或者字节 {@code b} 或字节 {@code c} 不匹配位模式 {@code 10xxxxxx}，
     * 则抛出 {@code UTFDataFormatException}。否则，该组转换为字符：
     * <pre>{@code
     * (char)(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F))
     * }</pre>
     * 如果组的第一个字节匹配模式 {@code 1111xxxx} 或模式 {@code 10xxxxxx}，则抛出 {@code UTFDataFormatException}。
     * <p>
     * 如果在整个过程的任何时间遇到文件结束，则抛出 {@code EOFException}。
     * <p>
     * 通过此过程将每个组转换为字符后，按从输入流中读取其对应组的相同顺序收集字符，
     * 以形成返回的 {@code String}。
     * <p>
     * 接口 {@code DataOutput} 的 {@code writeUTF} 方法可用于写入适合此方法读取的数据。
     * @return     Unicode 字符串。
     * @exception  EOFException            如果此流在读取所有字节之前到达末尾。
     * @exception  IOException             如果发生 I/O 错误。
     * @exception  UTFDataFormatException  如果字节不代表字符串的有效修改版 UTF-8 编码。
     */
    String readUTF() throws IOException;
}
